/**
* 版权声明：厦门睿商网络科技有限公司 版权所有 违者必究
* 日    期：2020-05-18
*/
package com.rzico.order.controller.member;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.rzico.account.entity.Refunds;
import com.rzico.account.model.Attach;
import com.rzico.account.service.RefundsService;
import com.rzico.annotation.Log;
import com.rzico.base.BaseController;
import com.rzico.base.CommResult;
import com.rzico.basics.entity.Enterprise;
import com.rzico.basics.entity.Member;
import com.rzico.basics.service.EnterpriseService;
import com.rzico.basics.service.MemberService;
import com.rzico.core.entity.SysEmployee;
import com.rzico.core.entity.SysFile;
import com.rzico.core.entity.SysOffice;
import com.rzico.core.service.SysEmployeeService;
import com.rzico.core.service.SysFileService;
import com.rzico.core.service.SysOfficeService;
import com.rzico.core.service.SysSequenceService;
import com.rzico.entity.PageResult;
import com.rzico.entity.Pageable;
import com.rzico.order.entity.*;
import com.rzico.order.enumx.OrderShippingStatusEnum;
import com.rzico.order.enumx.ShippingStatusEnum;
import com.rzico.order.service.*;
import com.rzico.util.StringUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import net.bytebuddy.asm.Advice;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;

/**
 * 退货申请单控制层
 *
 * @author Rzico Boot
 * @version 1.0
 * @date 2020-05-18
 */
@Api(description = "退货申请单接口")
@RestController
@RequestMapping("/member/askfor")
public class AskforController extends BaseController {

    @Autowired
    private AskforService askforService;

    @Autowired
    private AskforLogService askforLogService;

    @Autowired
    private AskforItemService askforItemService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private OrderItemService orderItemService;

    @Autowired
    private MemberService memberService;

    @Autowired
    private EnterpriseService enterpriseService;

    @Autowired
    private SysSequenceService sysSequenceService;

    @Autowired
    private SysFileService sysFileService;

    @Autowired
    private RefundsService refundsService;

    @Autowired
    private GiftCardService giftCardService;


    @Autowired
    private RabbitTemplate rabbitTemplate;


    /**
     * 分页查询退货申请单
     *
     * @return
    */
    @ApiOperation("分页查询退货申请单")
    @GetMapping("/list")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "status", value = "状态", dataType = "Integer", paramType = "query")
    })
    public CommResult<Askfor> list(Integer status, Pageable pageable) {
        Map<String, Object> params = new HashMap<String, Object>();
        params = buildSortField(params, pageable);

        Member member = memberService.getCurrent();
        if (member!=null) {
            params.put("memberId", member.getId());
        } else {
            return CommResult.error("没有登录");
        }

        if (null != status){
            params.put("status", status);
        }

        Page<Object> startPage = PageHelper.startPage(pageable.getPageNum(), pageable.getPageSize());
        List<Askfor> list = askforService.selectList(params);
        PageResult<Askfor> pageResult = new PageResult<Askfor>(list, startPage.getTotal(), pageable);
        return CommResult.success(pageResult);
    }

    /**
     * 查询单条退货申请单
     *
     * @return
    */
    @ApiOperation("查询单条退货申请单")
    @GetMapping("/find/{id}")
    public CommResult<Askfor> find(@PathVariable String id) {
        Askfor result = askforService.findById(id);

        Map<String,Object> data = new HashMap<>();
        data.put("askfor",result);

        result.setItemList(askforItemService.getItemList(result.getId()));

        Map<String,Object> paymentParams = new HashMap<>();
        paymentParams.put("orderType",0);
        paymentParams.put("orderId",id);
        paymentParams.put("success",1);

        data.put("refunds",refundsService.selectList(paymentParams));

        Map<String,Object> params = new HashMap<>();
        params.put("orderId",result.getId());
        params.put("orderType","askfor");
        data.put("files",sysFileService.selectList(params));

        Map<String,Object> logPrms = new HashMap<>();
        logPrms.put("askforId",id);
        logPrms.put("sortField","id");
        logPrms.put("sortType","desc");
        data.put("askforLog",askforLogService.selectList(logPrms));

        return CommResult.success(data);

    }

    /**
     * 批量删除退货申请单
     *
     * @param ids
     * @return
     */
    @Log(desc = "批量删除退货申请单", type = Log.LOG_TYPE.DEL)
    @ApiOperation("批量删除退货申请单,ids用逗号拼接")
    @PostMapping("/del/{ids}")
    public CommResult<Askfor> del(@PathVariable String ids) {

        askforService.deleteByIds(ids.split(","));
        return CommResult.success();
    }

    /**
     * 计算退款金额
     *
     * @param id
     * @return
     */
    @ApiOperation("计算退款金额")
    @PostMapping("/calculate/{id}")
    @ApiImplicitParams({

    })
    public CommResult<Askfor> calculate(@PathVariable Long id, @RequestBody List<OrderItem> itemList) {

        //1、检查销售订单是否存在
        Order order = orderService.selectByPrimaryKey(id);
        if (null == order){
            return CommResult.error("订单没找到");
        }

        //2、检查发货数量，并封装需要保存的orderItemList
        List<OrderItem> targetList = new ArrayList<>();
        for (OrderItem paramItem : itemList){
            OrderItem target = orderItemService.selectByPrimaryKey(paramItem.getId());
            target.setQuantity(paramItem.getReturnQuantity());
            targetList.add(target);
        }

        order.setItemList(itemList);
        Askfor askfor = askforService.calculate(order);

        return CommResult.success(askfor);
    }


    /**
     * 发起退款
     *
     * @param orderId
     * @return
     */
    @ApiOperation("发起退款")
    @PostMapping("/returns/{orderId}")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "reason", value = "退货理由", dataType = "Integer", paramType = "query"),
            @ApiImplicitParam(name = "memo", value = "补充说明", dataType = "Integer", paramType = "query")
    })
    public CommResult<Askfor> returns(@PathVariable Long orderId,String reason,String memo, @RequestBody List<OrderItem> itemList) {

        Order order = orderService.selectByPrimaryKey(orderId);
        if (order.getGiftCardId()!=null) {
            return CommResult.error("礼卡订单不能退");
        }
        if (order.getGroupBuyId()!=null) {
            return CommResult.error("团购订单不能退");
        }
        if (order.getBargainBuyId()!=null) {
            return CommResult.error("砍价订单不能退");
        }


        Enterprise enterprise = enterpriseService.selectByPrimaryKey(order.getEnterpriseId());
        if (enterprise.getAllowReturn()!=null && enterprise.getAllowReturn()==false) {
            if (order.getShippingStatus().equals(OrderShippingStatusEnum.SHIPPING_STATUS_SHIPPNG.getId())) {
                return CommResult.error("退货请联系客服");
            }
        }

        //检查退货状态
        Map<String,Object> params = new HashMap<>();
        params.put("orderId",orderId);

        Integer w = giftCardService.selectRowCount(params);
        if (w>0) {
            return CommResult.error("已生成礼卡");
        }


        params.put("askfored",true);
        w = askforService.selectRowCount(params);
        if (w>0) {
            return CommResult.error("不能重复退款");
        }

        Askfor askfor = null;
        try {
            askfor = askforService.askfor(orderId, itemList, sysSequenceService.generate("askfor"), reason, memo);
        } catch (Exception e) {
            return CommResult.error(e.getMessage());
        }

        //检查是否符合极速退款条件
        List<OrderItem> orderItemList = orderItemService.getItemList(askfor.getOrderId());

        BigDecimal shippingQuantity = BigDecimal.ZERO;
        BigDecimal returnedQuantity = BigDecimal.ZERO;
        BigDecimal quantity = BigDecimal.ZERO;
        for (OrderItem orderItem:orderItemList) {
            shippingQuantity = shippingQuantity.add(orderItem.getShippedQuantity());
            returnedQuantity = returnedQuantity.add(orderItem.getReturnQuantity());
            quantity = quantity.add(orderItem.getQuantity());
        }

        returnedQuantity = returnedQuantity.add(askfor.getSubQuantity());

        if (shippingQuantity.compareTo(BigDecimal.ZERO)==0 && returnedQuantity.compareTo(quantity)>=0) {
            Date d = DateUtils.addMinutes(new Date(),-30);
            if (order.getCreateDate().after(d)) {

                try {
                    askforService.confirm(askfor.getId());
                    List<Refunds> refundsList = askforService.refund(askfor.getId(), sysSequenceService.generate("refunds"));
                    for (Refunds refunds:refundsList) {
                        //TODO发送退款通知
                        Attach attachQueue = new Attach();
                        attachQueue.setCode("0000");
                        attachQueue.setId(String.valueOf(refunds.getId()));
                        attachQueue.setQueue("queue.refunds.submit");
                        Message message = MessageBuilder
                                .withBody(JSON.toJSONString(attachQueue).getBytes())
                                .setContentType(MessageProperties.CONTENT_TYPE_JSON)
                                .build();
                        CorrelationData correlationData = new CorrelationData();
                        correlationData.setId(UUID.randomUUID().toString());
                        logger.info("发送 MQ");
                        rabbitTemplate.convertAndSend("directExchange",attachQueue.getQueue()+".key", message, correlationData);

                    }
                } catch (Exception e) {
                    logger.error(e.getMessage());
                }

            }
        }

        askfor = askforService.findById(askfor.getId());
        return CommResult.success(askfor);

    }

    /**
     * 退货寄回
     *
     * @param id
     * @return
     */
    @ApiOperation("退货寄回")
    @PostMapping("/shipping/{id}")
    public CommResult<Askfor> shipping(@PathVariable Long id, @RequestBody List<AskforItem> itemList) {
        int affectCount = askforService.shipping(id, itemList);
        if (affectCount <= 0){
            return CommResult.error();
        }
        Askfor askfor = askforService.findById(id);
        return CommResult.success(askfor);
    }

    /**
     * 撤消退款
     *
     * @param id
     * @return
     */
    @ApiOperation("撤消退款")
    @PostMapping("/cancel/{id}")
    public CommResult<Askfor> cancel(@PathVariable Long id) {
        try {
            int affectCount = askforService.cancel(id);
            if (affectCount <= 0){
                return CommResult.error();
            }
            Askfor askfor = askforService.findById(id);
            return CommResult.success(askfor);
        } catch (Exception e) {
            logger.error(e.getMessage());
            return CommResult.error(e.getMessage());
        }
    }

}
